package com.shelpe.services.sinbad.controller;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.Assert;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;

import com.fasterxml.jackson.annotation.JsonProperty;
import com.shelpe.services.sinbad.entity.TaobaoTopKeyword;
import com.shelpe.services.sinbad.entity.jpa.Category;
import com.shelpe.services.sinbad.entity.jpa.Product;
import com.shelpe.services.sinbad.entity.jpa.TaobaoTopCategory;
import com.shelpe.services.sinbad.repository.jpa.CategoryRepository;
import com.shelpe.services.sinbad.repository.jpa.ProductRepository;
import com.shelpe.services.sinbad.repository.jpa.TaobaoTopCategoryRepository;
import com.shelpe.services.sinbad.repository.jpa.TaobaoTopKeywordRepository;

import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;

@RestController
@RequestMapping("/sinbadservice")
@Slf4j
@Api(value = "类目相关的API", consumes = "application/json", produces = "application/json")
public class CategoryController {

	@Autowired
	private ProductRepository productRepository;
	@Autowired
	private CategoryRepository categoryRepository;
	@Autowired
	private TaobaoTopCategoryRepository taobaoTopCategoryRepository;
	@Autowired
	private TaobaoTopKeywordRepository taobaoTopKeywordRepository;

	@ApiOperation(value = "获取排行榜类目词")
	@RequestMapping(method = RequestMethod.POST, path = "/tops/categorys")
	public TaobaoTopCategoryDto createTaobaoTopCategory(@RequestBody TaobaoTopCategoryDto dto) {
		TaobaoTopCategory top = null;
		if (dto.getLevel() != 2) {
			top = this.taobaoTopCategoryRepository.findTopByCategory(dto.getCategory());
		} else {
			top = this.taobaoTopCategoryRepository.findTopByLeafID(dto.getLeafID());
		}
		if (top == null) {
			top = new TaobaoTopCategory();
		}
		BeanUtils.copyProperties(dto, top);
		this.taobaoTopCategoryRepository.save(top);
		dto.setKeyID(top.getAutoID());

		return dto;
	}

	@ApiOperation(value = "获取排行榜关键词")
	@RequestMapping(method = RequestMethod.POST, path = "/tops/keywords")
	public List<TaobaoTopKeywordDto> createTaobaoTopKeyword(@RequestBody List<TaobaoTopKeywordDto> keywords) {
		Assert.notEmpty(keywords);
		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
		for (TaobaoTopKeywordDto dto : keywords) {
			TaobaoTopKeyword top = this.taobaoTopKeywordRepository.findByLeafIDAndTypeAndWord(dto.getLeafID(),
					TaobaoTopKeyword.Type.from(dto.getType()), dto.getWord());
			if (top == null) {
				top = new TaobaoTopKeyword();
				top.setCreateTime(new Date());
			}
			try {
				top.setSyncTime(sdf.parse(dto.getSyncTime()));
			} catch (ParseException e) {
				log.error("ParseException:{}", e);
			}
			BeanUtils.copyProperties(dto, top);
			top.setType(TaobaoTopKeyword.Type.from(dto.getType()));
			this.taobaoTopKeywordRepository.save(top);
		}

		return keywords;
	}

	@Data
	public static class TaobaoTopKeywordDto {
		@JsonProperty("leaf_id")
		private Long leafID;
		private String type;
		private Integer position;
		private String word;
		private String url;
		@JsonProperty("look_index")
		private String lookIndex;
		@JsonProperty("up_or_down")
		private Integer upOrDown;
		private Integer change;
		private String ranges;
		@JsonProperty("sync_time")
		private String syncTime;
	}

	@Data
	public static class TaobaoTopCategoryDto {
		@JsonProperty("auto_id")
		private Long keyID;
		private Long pid;
		@JsonProperty("top_id")
		private String topID;
		private String category;
		@JsonProperty("leaf_id")
		private Long leafID;
		private Integer level;
	}

	@ApiOperation(value = "获取用户的主营类目", notes = "由于目前拿不全所有宝贝的所属类目，有可能拿不到用户的主营类目。")
	@RequestMapping(method = RequestMethod.GET, path = "/users/{user_id}/categories/@primary")
	public FoundRes findPrimaryCategory(@PathVariable("user_id") long userID) {
		Map<Long, Integer> duplidates = new HashMap<Long, Integer>();
		Map<Long, Category> cache = new HashMap<Long, Category>();
		FoundRes res = new FoundRes();
		List<Product> salestProds = this.productRepository.findTop10ByUserIDOrderBySalesDesc(userID);
		
		//拿不到主营类目
		if(salestProds==null||salestProds.size()==0) {
			res.setFound(false);
			return res;
		}
		
		for (Product prod : salestProds) {
			if (prod.getCategoryID() > 0) {
				Category rootCat = this.findRootCategory(cache, prod.getCategoryID());
				log.debug("root category: {}", rootCat);
				if (rootCat != null) {
					int pre = duplidates.containsKey(rootCat.getCategoryID()) ? duplidates.get(rootCat.getCategoryID())
							: 0;
					duplidates.put(rootCat.getCategoryID(), pre + 1);
				}
			}
		}

		long maxDuplicate = 0;
		long foundCategoryID = 0;
		for (Entry<Long, Integer> entry : duplidates.entrySet()) {
			if (entry.getValue() > maxDuplicate) {
				maxDuplicate = entry.getKey();
				foundCategoryID = entry.getKey();
			}
		}

		if (foundCategoryID > 0) {
			Category cat = cache.get(foundCategoryID);
			res.setCategory(new CategoryDto());
			res.getCategory().setCategoryID(cat.getCategoryID());
			res.getCategory().setCategoryName(cat.getName());
		} else {
			res.found = false;
		}

		return res;
	}

	private Category findRootCategory(Map<Long, Category> cache, long categoryID) {
		Category cat = cache.get(categoryID);
		if (cat == null) {
			cat = this.categoryRepository.findOne(categoryID);
			if (cat != null) {
				cache.put(categoryID, cat);
			}
		}
		if (cat != null && cat.getParentID() > 0) {
			cat = this.findRootCategory(cache, cat.getParentID());
		}
		return cat;
	}

	@Data
	public static class CategoryDto {
		@JsonProperty("category_id")
		long categoryID;
		@JsonProperty("category_name")
		String categoryName;
	}

	@Data
	public static class FoundRes {
		private boolean found = true;
		private CategoryDto category;
	}
}
